(function($){
    $.fn.tblPaging = function(settings) {
        var tbody = null;
        var cache = [];
        var filterDataHolder = {};
        
        var defaults = {  
            prevArrow :         (new Image()).src="/images/pager/prev.png",  
            prevArrowGrey :     (new Image()).src="/images/pager/prev_gray.png",
            nextArrow :         (new Image()).src="/images/pager/next.png",
            nextArrowGrey :     (new Image()).src="/images/pager/next_gray.png",
            loader :            (new Image()).src="/images/css/indicator.gif",
            
            prevPageId:     '#IDTablePagination_prevPage',
            nextPageId:     '#IDTablePagination_nextPage',
            tblPgnTxt:      '.tablePagination_text',
            // filter holder
            filterClasses: {
                fltBtnBusinessUnit: ".filterBusinessUnit",
                fltBtnDepartment: ".filterDepartment",
                fltBtnJobTitle: ".filterJobTitle"
            },
            
            
            rowsPerPage : window.gbl_var.employeeCount,
            currPage : 1,
            failureMsg: "Fail load data",
            url: "",
            numRows: 0,
            filterEnable: true,
            onLoad: function(){}
        };
        settings = $.extend(defaults, settings);
        self = this; // Hach of this outside of the method scope
        // Public Methods
        this.getherDataParams = function(){
            var dataParams = {};
            dataParams.start = settings.currPage;
            dataParams.offset = settings.rowsPerPage;
            for(index in filterDataHolder){
                dataParams[index] = filterDataHolder[index];
            }
            return dataParams;
        }

        return this.each(function(index) {
            tbody = $(this).children()[1];
            // First load data
            loadData();
            
            // Event binding
            $(settings.nextPageId).bind('click', function (e) {
                goForward();
            });
            $(settings.prevPageId).bind('click', function (e) {
                goBackward();
            });
        });
        // Privat methods
        // Load data from renge
        // !enable cache 
        function loadData(enable){
            // Preloader
            showTblIndicator();
            if(cache[settings.currPage] && !enable){
                $(tbody).html(cache[settings.currPage]);
                createPaginationElements(settings.numRows);
                addColumnFilters();
                tableSorter();
            }else{
                $.ajax({
                    url: "/users",
                    data: self.getherDataParams(),
                    success: function(data){
                        // Fill cache data
                        cache[settings.currPage] = data;
                        // Clear data
                        $(tbody).html("");
                        // Prefilling data
                        $(tbody).html(data);
                        loadCountAndShowPgn();
                        addColumnFilters();
                        tableSorter();
                        if(settings.onLoad && $.isFunction(settings.onLoad)){
                            settings.onLoad();
                        }
                    },
                    error:  function(jqXHR, textStatus, errorThrown){
                        hideTmlIndicator();
                    }
                });
            }
        }
        // Load count 
        function loadCountAndShowPgn(){
            $.ajax({
                url: "/users/total_count",
                data: self.getherDataParams(),
                success: function(data){
                    createPaginationElements(data);
                },
                error:  function(jqXHR, textStatus, errorThrown){
                    // Failure
                }
            });
        }
        // Firstly load data
        function createPaginationElements(numRows) {
            // condition controller
            settings.numRows = parseInt(numRows);
            var start = settings.currPage;
            var end = settings.currPage  + settings.rowsPerPage;
            
            if(start >= settings.numRows){
                settings.currPage = 1;
                loadData();
                // Remade values
                start = settings.currPage;
                end = settings.currPage  + settings.rowsPerPage;
            }else if(end > settings.numRows){
                end = settings.numRows;
            }else if(start < 1){
                settings.currPage = 1;
                cache = [];
                loadData();
                // Remade values
                start = settings.currPage;
                end = settings.currPage  + settings.rowsPerPage;
            }
            // condition controller
            
            // Button controller
            if(settings.currPage == 1)
                $(settings.prevPageId).attr("src", settings.prevArrowGrey);
            else
                $(settings.prevPageId).attr("src", settings.prevArrow);

                
            if ((settings.currPage  + settings.rowsPerPage) < settings.numRows)
                $(settings.nextPageId).attr("src",settings.nextArrow);
            else
                $(settings.nextPageId).attr("src",settings.nextArrowGrey);
            
            $(settings.tblPgnTxt).text(start + " - " + end + " of " + settings.numRows);
        }
        // Show load indicator
        function showTblIndicator(){
            $(tbody).html("<tr><td COLSPAN=9><center><img src='" + settings.loader +  "'></center></td></tr>");
        }
        // Hide load indicator
        function hideTmlIndicator(){
            $(tbody).html("<tr><td COLSPAN=9><center>" + settings.failureMsg + "</center></td></tr>");
        }
        employee
        function showPaginator(numRows){
            $("#topPagination").html(createPaginationElements(numRows));
        }
        // Go forward
        function goForward(){
            settings.currPage = settings.currPage + settings.rowsPerPage;
            loadData();
        }
        // Go backward
        function goBackward(){
            settings.currPage = settings.currPage - settings.rowsPerPage;
            loadData();
        }
        // Filtering
        function addColumnFilters(){
            // Filtering enamble
            if (settings.filterEnable) {
                for(index in settings.filterClasses){
                    // Closures for eventing
                    function closeresFilter(fltName){
                        var filterName = fltName;
                        function executorReturned(e){
                            filterCall(filterName, e, this);
                        }
                        return executorReturned;
                    }
                    // Clear events
                    $(settings.filterClasses[index]).find("A").unbind('click');
                    $(settings.filterClasses[index]).find("A").bind('click', closeresFilter(index) );
                }
                // eventing
                for (index in settings.filterClasses) {
                    // Closures for eventing
                    function closeresFilterButton(fltBtnName){
                        var filterButtonName = fltBtnName;
                        function executorReturnedButton(e){
                            clearParticularFilter(filterButtonName, e, this);
                        }
                        return executorReturnedButton;
                    }
                    //Clear data eeevents
                    $("." + index).unbind('click');
                    $("." + index).bind('click', closeresFilterButton(index) );
                }
            }
        }
        
        function filterCall(filterBtnName, event, targetobject){
            // Clear current page
            settings.currPage = 1;
            
            var filterName = settings.filterClasses[filterBtnName];
            var colName = filterName.split("filter")[1];
            var colVal = $(targetobject).text();
            
            filterDataHolder[colName]=colVal;
            filterTogler();
            
            //Clear cache
            cache = [];
            loadData(true);
        }
        function clearParticularFilter(filterButtonName, event, targetObj){
            // Clear current page
            settings.currPage = 1;
            
            var calName = filterButtonName.split("fltBtn")[1];
            delete filterDataHolder[calName];
            filterTogler();
            //Clear cache
            cache = []
            loadData(true);
        }
        
        function filterTogler(){
            for(index in settings.filterClasses){
                var calName = index.split("fltBtn")[1];
                if(filterDataHolder[calName]){
                    $("." + index).css("visibility", "visible");
                }else{
                    $("." + index).css("visibility", "hidden");
                }
            }
        }

        // Sorter 
        function tableSorter(){
            $('#tblDetails').trigger("update");
            $("#tblDetails").tablesorter("sorton",
            {
                //sortList: [[1, 0]], 
                headers: {
                    // assign the secound column (we start counting zero) 
                    0: {
                        // disable it by setting the property sorter to false 
                        sorter: false
                    },
                    // assign the third column (we start counting zero) 
                    3: {
                        // disable Dept filter by setting the property sorter to false 
                        sorter: false
                    },
                    // assign the third column (we start counting zero) 
                    5: {
                        // disable Dept filter by setting the property sorter to false 
                        sorter: false
                    },
                    // assign the third column (we start counting zero) 
                    7: {
                        // disable job title fiter by setting the property sorter to false
                        sorter: false
                    },
                    9: {
                        // disable job title fiter by setting the property sorter to false
                        sorter: false
                    }
                }
            });
        }
    };
})(jQuery);